%include	"pm.inc"
	org	0x7c00
LABEL_START:
	jmp	LABEL_BEGIN
	
	[SECTION .s16]
	[bits 16]
LABEL_BEGIN:
	mov	ax, cs
	mov	ds, ax
	mov	es, ax
	mov	ss, ax
	mov	sp, 0100h
	

	; 初始化 32 位代码段描述符
	xor	eax, eax
	mov	ax, cs
	shl	eax, 4
	add	eax, LABEL_SEG_CODE32
	mov	word [LABEL_DESC_CODE32 + 2], ax
	shr	eax, 16
	mov	byte [LABEL_DESC_CODE32 + 4], al
	mov	byte [LABEL_DESC_CODE32 + 7], ah

	; 为加载 GDTR 作准备
	xor	eax, eax
	mov	ax, ds
	shl	eax, 4
	add	eax, LABEL_GDT
	mov	dword [GdtPtr + 2], eax

	; 加载 GDTR
	lgdt	[GdtPtr]

	; 关中断
	cli

	; 打开地址线A20
	in	al, 92h
	or	al, 00000010b
	out	92h, al

	; 准备切换到保护模式
	mov	eax, cr0
	or	eax, 1
	mov	cr0, eax

	; 真正进入保护模式
	jmp	dword SelectorCode32:0	; 执行这一句会把 SelectorCode32 装入 cs,
					; 并跳转到 Code32Selector:0  处

	
SECTION16_LEN	equ	$ - $$

[SECTION	.gdt]
LABEL_GDT:		Descriptor	0, 	0,	0
LABEL_DESC_CODE32:	Descriptor	0, 	SegCode32Len - 1, DA_C + DA_32
LABEL_DESC_VIDEO:	Descriptor	0B8000h,0ffffh, DA_DRW
GdtLen		equ	$ - LABEL_GDT
GdtPtr		dw	GdtLen	- 1
		dd	0

SelectorCode32	equ	LABEL_DESC_CODE32	-	LABEL_GDT
SelectorVideo	equ	LABEL_DESC_VIDEO	-	LABEL_GDT
	GDT_LEN	equ	$ - $$

	[SECTION	.s32]
	[BITS	32]
LABEL_SEG_CODE32:
	mov	ax, SelectorVideo
	mov	gs, ax
	mov	edi, (80 * 11 + 79) * 2
	mov	ah, 0Ch
	mov	al, 'A'
	mov	[gs:edi], ax

	jmp $

SegCode32Len	equ	$ - LABEL_SEG_CODE32

message:	        db 'hello, world', 13, 10, 0
	; 填充剩下的空间，使生成的二进制代码恰好为512字节
	times   501-($-$$) - SECTION16_LEN - GDT_LEN    db      0 
	dw      0xaa55	; 结束标志
	